# -*- coding: utf-8 -*-
from __future__ import absolute_import

import os
import sys
from copy import deepcopy
from datetime import timedelta

from sqlalchemy import func

# add up one level dir into sys path

sys.path.append(os.path.abspath(os.path.dirname(os.path.dirname(__file__))))
os.environ['DJANGO_SETTINGS_MODULE'] = 'base.settings'

from common import orm
from common.pay.model import Pay
from common.transaction.model import Withdraw
from common.coupon.model import AccountCoupon, COUPON_STATUS
from common.stats import MG_BIGBANG_COLL as mg
from common.utils.tz import get_utc_date, local_now, utc_to_local
from common import slave
from common.account.model.account import Account
from tools.bull_report import create_bull_report
from tools.kfc_report import create_kfc_report
from tools.lottery_report import create_lottery_report
from tools.fruit_report import create_fruit_report
from tools.metis_report import create_metis_report
from argparse import ArgumentParser


def create_channel_report(day):
    end = day + timedelta(days=1)
    value = {}
    # 新增设备，根据渠道聚合
    items = mg.device_stats.aggregate([
        {"$match": {"created_at": {"$gte": day, "$lt": end}}},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})["new_device"] = item["count"]
    # 活跃设备
    items = mg.device_stats.aggregate([
        {"$match": {"updated_at": {"$gte": day}}},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})['active_device'] = item["count"]
    # 新用户
    items = mg.user_stats.aggregate([
        {"$match": {"created_at": {"$gte": day, "$lt": end}}},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})['new_user'] = item["count"]
    # 新注册设备
    cond = [
        {'$match': {'$and': [
            {'created_at': {'$gte': day, "$lt": end}},
            {'register_at': {'$exists': 1}}
        ]}},
        {'$group': {'_id': '$chn', 'count': {'$sum': 1}}}
    ]
    items = mg.device_stats.aggregate(cond)
    for item in items:
        value.setdefault(item['_id'], {})[
            'new_register_device'] = item['count']
    # 活跃用户
    items = mg.user_stats.aggregate([
        {"$match": {"updated_at": {"$gte": day}}},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})['active_user'] = item['count']
    # 活跃用户中已注册用户
    items = mg.user_stats.aggregate([
        {"$match": {
            "updated_at": {"$gte": day, "$lt": end},
            "register_at": {"$exists": 1}
        }},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})['active_register_user'] = item['count']
    # 玩过游戏的用户
    items = mg.user_stats.aggregate([
        {"$match": {
            "updated_at": {"$gte": day, "$lt": end},
            "$or":[{"pay":{"$exists":1}},
                   {"lottery":{"$exists":1}},
                   {"kfc":{"$exists":1}},
                   {"fruit":{"$exists":1}},
                   {"bull":{"$exists":1}}]
        }},
        {"$group": {"_id": "$chn", "count": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item['_id'], {})['play_user'] = item['count']
    # 总付费（充值）人数/金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$recharge.total"},
                    "count": {"$sum": "$recharge.count"}}}
    ])
    for item in items:
        t = value.setdefault(item["_id"], {})
        t['recharge_user'] = item['total']
        t['recharge_price'] = item['price']
        t['recharge_count'] = item['count']
    # 总付费设备数
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$aid", "chn": {"$first": "$chn"}}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item["_id"], {})["recharge_device"] = item['total']
    # 渠道用户参与人数/金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"pay.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$pay.total"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['pay_user'] = item['total']
        t['pay_price'] = item['price']
    # 新用户付费人数/金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$recharge.total"},
                    "count": {"$sum": "$recharge.count"},
                   }}
    ])
    for item in items:
        t = value.setdefault(item["_id"], {})
        t['new_recharge_user'] = item['total']
        t['new_recharge_price'] = item['price']
        t['new_recharge_count'] = item['count']
    # 用户提现人数/金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"withdraw.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$withdraw.total"}}}
    ])
    for item in items:
        t = value.setdefault(item["_id"], {})
        t['withdraw_count'] = item['total']
        t['withdraw_price'] = item['price']
    # 新用户退款人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {'updated_at': {'$gte': day, "$lt": end}},
            {'refund.total': {'$gt': 0}}
        ]}},
        {"$group": {"_id": "$chn", 'total': {'$sum': 1},
                    'price': {'$sum': '$refund.total'}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['new_refund_user'] = item['total']
        t['new_refund_price'] = item['price']
    # 新增付费设备
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": '$aid', "chn": {"$first": "$chn"}}},
        {"$group": {"_id": '$chn', "total": {"$sum": 1}}}
    ])
    for item in items:
        value.setdefault(item["_id"], {})[
            'new_recharge_device'] = item['total']
    # 真实用户中奖人数/金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"win.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$win.total"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['win_count'] = item['total']
        t['win_price'] = item['price']
    # 加奖人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"bonus.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$bonus.total"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['bonus_count'] = item['total']
        t['bonus_price'] = item['price']

    # 红包消耗
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"coupon.use": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": "$coupon.use"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['coupon_use'] = item.get('total', 0)

    # 充值回饋
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge_bonus.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$recharge_bonus.total"},
                    "count": {"$sum": "$recharge_bonus.count"}}}
    ])
    for item in items:
        t = value.setdefault(item["_id"], {})
        t['recharge_bonus_user'] = item['total']
        t['recharge_bonus_price'] = item['price']
        t['recharge_bonus_count'] = item['count']

    # 每日上分數據
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"system_recharge.total": {"$exists": True}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "price": {"$sum": "$system_recharge.total"},
                    "count": {"$sum": "$system_recharge.count"}}}
    ])
    for item in items:
        t = value.setdefault(item["_id"], {})
        t['system_recharge_user'] = item['total']
        t['system_recharge_price'] = item['price']
        t['system_recharge_count'] = item['count']

    # kfc人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"kfc.bet_amount": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "bet": {"$sum": "$kfc.bet_amount"},
                    "award": {"$sum": "$kfc.award_amount"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['kfc_count'] = item['total']
        t['kfc_price'] = item['bet']
        t['kfc_award'] = item['award']

    # bull人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"bull.bet_amount": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "bet": {"$sum": "$bull.bet_amount"},
                    "lose": {"$sum": "$bull.lose_amount"},
                    "win": {"$sum": "$bull.win_amount"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['bull_count'] = item['total']
        t['bull_price'] = item['bet'] - item['lose']
        t['bull_award'] = item['win']

    # fruit人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"fruit.bet_amount": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "bet": {"$sum": "$fruit.bet_amount"},
                    "win": {"$sum": "$fruit.win_amount"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['fruit_count'] = item['total']
        t['fruit_price'] = item['bet']
        t['fruit_award'] = item['win']

    # lottery人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"lottery.bet_amount": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "bet": {"$sum": "$lottery.bet_amount"},
                    "win": {"$sum": "$lottery.win_amount"}}}
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['lottery_count'] = item['total']
        t['lottery_price'] = item['bet']
        t['lottery_award'] = item['win']

    # metis人数／金额
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"metis.total_bet": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$chn", "total": {"$sum": 1},
                    "bet": {"$sum": "$metis.total_bet"},
                    "profit": {"$sum": "$metis.total_profit"},
                    "lose": {"$sum": "$metis.total_lose"}
                    }
         }
    ])
    for item in items:
        t = value.setdefault(item['_id'], {})
        t['metis_count'] = item['total']
        t['metis_price'] = item['bet']
        t['metis_profit'] = item['profit']
        t['metis_lose'] = item['lose']

    d = utc_to_local(day).strftime('%Y-%m-%d')
    for k, v in value.iteritems():
        _id = '%s-%s' % (d, k)
        v['day'] = d
        v['chn'] = k
        v['profit'] = v.get('recharge_price', 0) - v.get('withdraw_price', 0)
        v['profit_rate'] = v['profit'] / v.get('recharge_price') if v.get('recharge_price') else 0
        mg.channel_report.update_one({'_id': _id}, {'$set': v}, upsert=True)


def create_daily_report(day):
    end = day + timedelta(days=1)
    value = {}
    # 每日上分數據
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"system_recharge.total": {"$exists": True}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$system_recharge.total"},
                    "count": {"$sum": "$system_recharge.count"}}}
    ])
    item = items.next() if items.alive else {}
    value['system_recharge_user'] = item.get('total', 0)
    value['system_recharge_price'] = item.get('price', 0)
    value['system_recharge_count'] = item.get('count', 0)
    # 每日metis數據
    items = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"metis.total_bet": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "bet": {"$sum": "$metis.total_bet"},
                    "profit": {"$sum": "$metis.total_profit"}}}
    ])
    item = items.next() if items.alive else {}
    value['metis_count'] = item.get('total', 0)
    value['metis_price'] = item.get('bet', 0)
    value['metis_profit'] = item.get('profit', 0)

    # 新增设备
    t = mg.device_stats.aggregate([
        {"$match": {"created_at": {"$gte": day, "$lt": end}}},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['new_device'] = t.get('count', 0)
    # 活跃设备
    t = mg.device_stats.aggregate([
        {"$match": {"updated_at": {"$gte": day}}},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['active_device'] = t.get('count', 0)
    # 新用户
    t = mg.user_stats.aggregate([
        {"$match": {"created_at": {"$gte": day, "$lt": end}}},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['new_user'] = t.get('count', 0)
    # 新注册设备
    cond = [
        {'$match': {'$and': [
            {'created_at': {'$gte': day, "$lt": end}},
            {'register_at': {'$exists': 1}}
        ]}},
        {'$group': {'_id': None, 'count': {'$sum': 1}}}
    ]
    t = mg.device_stats.aggregate(cond)
    t = t.next() if t.alive else {}
    value["new_register_device"] = t.get('count', 0)
    # 活跃用户
    t = mg.user_stats.aggregate([
        {"$match": {"updated_at": {"$gte": day}}},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['active_user'] = t.get('count', 0)
    # 活跃用户中已注册用户
    t = mg.user_stats.aggregate([
        {"$match": {
            "updated_at": {"$gte": day, "$lt": end},
            "register_at": {"$exists": 1}
        }},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['active_register_user'] = t.get('count', 0)
    # 玩过游戏的用户
    t = mg.user_stats.aggregate([
        {"$match": {
            "updated_at": {"$gte": day, "$lt": end},
            "$or":[{"pay":{"$exists":1}},
                   {"lottery":{"$exists":1}},
                   {"kfc":{"$exists":1}},
                   {"fruit":{"$exists":1}},
                   {"bull":{"$exists":1}}]
        }},
        {"$group": {"_id": None, "count": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value['play_user'] = t.get('count', 0)
    # 总付费（充值）人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$recharge.total"},
                    "count": {"$sum": "$recharge.count"}}}
    ])
    t = t.next() if t.alive else {}
    value['recharge_user'] = t.get('total', 0)
    value['recharge_price'] = t.get('price', 0)
    value['recharge_count'] = t.get('count', 0)
    # 代理付费（充值）人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_wechat": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "wechat_total": {"$sum": 1},
                    "wechat_price": {"$sum": u"$recharge.agent_wechat"}}}
    ])
    t = t.next() if t.alive else {}
    value['agent_wechat_recharge_user'] = t.get('wechat_total', 0)
    value['agent_wechat_recharge_price'] = t.get('wechat_price', 0)
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_alipay": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "alipay_total": {"$sum": 1},
                    "alipay_price": {"$sum": u"$recharge.agent_alipay"}}}
    ])
    t = t.next() if t.alive else {}
    value['agent_alipay_recharge_user'] = t.get('alipay_total', 0)
    value['agent_alipay_recharge_price'] = t.get('alipay_price', 0)
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_union": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "union_total": {"$sum": 1},
                    "union_price": {"$sum": u"$recharge.agent_union"}}}
    ])
    t = t.next() if t.alive else {}
    value['agent_union_recharge_user'] = t.get('union_total', 0)
    value['agent_union_recharge_price'] = t.get('union_price', 0)
    value['agent_recharge_user'] = value['agent_union_recharge_user'] + value['agent_alipay_recharge_user'] + value['agent_wechat_recharge_user']
    value['agent_recharge_price'] = value['agent_union_recharge_price'] + value['agent_alipay_recharge_price'] + value['agent_wechat_recharge_price']
    # 总付费设备数
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$aid"}},
        {"$group": {"_id": None, "total": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}
    value["recharge_device"] = t.get('total', 0)
    # 渠道用户参与夺宝人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"pay.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$pay.total"}}}
    ])
    t = t.next() if t.alive else {}
    value['pay_user'] = t.get('total', 0)
    value['pay_price'] = t.get('price', 0)
    # 新用户付费人数／金额
    t = mg.user_stats.aggregate([
        {"$match": {"$and": [
        {"created_at": {"$gte": day, "$lt": end}},
        {"recharge.total": {"$gt": 0}}
    ]}},
        {"$group": {"_id":None, "total": {"$sum": 1},
                    "price": {"$sum": "$recharge.total"},
                    "count": {"$sum": "$recharge.count"},
                   }}
    ])
    t = t.next() if t.alive else {}
    value['new_recharge_user'] = t.get('total', 0)
    value['new_recharge_price'] = t.get('price', 0)
    value['new_recharge_count'] = t.get('count', 0)
    # 新用户代理付费人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_wechat": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "wechat_total": {"$sum": 1},
                    "wechat_price": {"$sum": u"$recharge.agent_wechat"}}}
    ])
    t = t.next() if t.alive else {}
    value['new_agent_wechat_recharge_user'] = t.get('wechat_total', 0)
    value['new_agent_wechat_recharge_price'] = t.get('wechat_price', 0)
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_alipay": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "alipay_total": {"$sum": 1},
                    "alipay_price": {"$sum": u"$recharge.agent_alipay"}}}
    ])
    t = t.next() if t.alive else {}
    value['new_agent_alipay_recharge_user'] = t.get('alipay_total', 0)
    value['new_agent_alipay_recharge_price'] = t.get('alipay_price', 0)
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {'is_fresh': 1},
            {"updated_at": {"$gte": day, "$lt": end}},
            {u"recharge.agent_union": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "union_total": {"$sum": 1},
                    "union_price": {"$sum": u"$recharge.agent_union"}}}
    ])
    t = t.next() if t.alive else {}
    value['new_agent_union_recharge_user'] = t.get('union_total', 0)
    value['new_agent_union_recharge_price'] = t.get('union_price', 0)
    value['new_agent_recharge_user'] = value['new_agent_union_recharge_user'] + value['new_agent_alipay_recharge_user'] + value['new_agent_wechat_recharge_user']
    value['new_agent_recharge_price'] = value['new_agent_union_recharge_price'] + value['new_agent_alipay_recharge_price'] + value['new_agent_wechat_recharge_price']
    # 真实用户夺宝中奖人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"win.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$win.total"}}}
    ])
    t = t.next() if t.alive else {}
    value['win_count'] = t.get('total', 0)
    value['win_price'] = t.get('price', 0)
    # 用户加奖人数／金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"bonus.total": {"$gt": 0}}
        ]}},
        {
            "$group": {"_id": None, "total": {"$sum": 1},
                       "price": {"$sum": "$bonus.total"}}}
    ])
    t = t.next() if t.alive else {}
    value['bonus_count'] = t.get('total', 0)
    value['bonus_price'] = t.get('price', 0)
    # 红包消耗
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"coupon.use": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": "$coupon.use"}}}
    ])
    t = t.next() if t.alive else {}
    value['coupon_use'] = t.get('total', 0)
    # 退款人数／金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"refund.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$refund.total"}}}
    ])
    t = t.next() if t.alive else {}
    value['refund_count'] = t.get('total', 0)
    value['refund_price'] = t.get('price', 0)
    # 用户提现人数/金额
    t = mg.daily_stats.aggregate([
        {"$match": {"$and": [
            {"updated_at": {"$gte": day, "$lt": end}},
            {"withdraw.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": None, "total": {"$sum": 1},
                    "price": {"$sum": "$withdraw.total"}}}
    ])
    t = t.next() if t.alive else {}
    value['withdraw_count'] = t.get('total', 0)
    value['withdraw_price'] = t.get('price', 0)
    # 新增付费设备
    t = mg.user_stats.aggregate([
        {"$match": {"$and": [
            {"register_at": {"$gte": day, "$lt": end}},
            {"recharge.total": {"$gt": 0}}
        ]}},
        {"$group": {"_id": "$aid"}},
        {"$group": {"_id": None, "total": {"$sum": 1}}}
    ])
    t = t.next() if t.alive else {}

    value['new_recharge_device'] = t.get('total', 0)
    # 实际利润: 真实用户充值 - 真实用户中奖成本
    value['profit'] = value['recharge_price'] - value['withdraw_price']
    value['profit_rate'] = value['profit'] / value['recharge_price'] if value['recharge_price'] else 0
    today = utc_to_local(day).strftime('%Y-%m-%d')
    mg.daily_report.update_one({'_id': today},
                               {'$set': value}, upsert=True)


def fix_daily_recharge(day):
    """
    有时日志统计会存在一定的误差，这个方法用于修正充值数据
    """
    end = day + timedelta(days=1)
    value = {}
    # 总付费（充值）人数/金额
    ret = orm.session.query(func.count(Pay), func.sum(Pay.price)).filter(
        Pay.updated_at>=day).filter(
        Pay.updated_at<=end).filter(
        Pay.status==2).first()
    value['recharge_count'] = ret[0] or 0
    value['recharge_price'] = float(ret[1] or 0)
    # 用户提现人数/金额
    ret = orm.session.query(func.count(Withdraw), func.sum(Withdraw.real_price)).filter(
        Withdraw.updated_at>=day).filter(
        Withdraw.updated_at<=end).filter(
        Withdraw.status==2).first()
    value['withdraw_count'] = ret[0] or 0
    value['withdraw_price'] = float(ret[1] or 0)
    value['profit'] = value['recharge_price'] - value['withdraw_price']
    value['profit_rate'] = value['profit'] / value[
        'recharge_price'] if value['recharge_price'] else 0
    today = utc_to_local(day).strftime('%Y-%m-%d')
    mg.daily_report.update_one({'_id': today},
                               {'$set': value}, upsert=True)
    orm.session.commit()


def update_stay_N_count(today, n):
    update_day = today - timedelta(days=n)
    e = update_day + timedelta(days=1)
    day = utc_to_local(update_day).strftime('%Y-%m-%d')
    cond = [
        {'$match': {'$and': [
            {'created_at': {'$gte': update_day, "$lt": e}},
            {'updated_at': {'$gt': today}}
        ]}},
        {'$group': {'_id': None, 'count': {'$sum': 1}}}
    ]
    if n == 1:
        n = 2
    to_set = {}
    # 设备次日留存
    t = mg.device_stats.aggregate(cond)
    t = t.next() if t.alive else {}
    to_set['stay_{}'.format(n)] = t.get('count', 0)
    # 用户次日留存
    t = mg.user_stats.aggregate(cond)
    t = t.next() if t.alive else {}
    to_set['user_stay_{}'.format(n)] = t.get('count', 0)
    mg.daily_report.update_one({'_id': day}, {'$set': to_set})
    # 按渠道更新：
    cond[1]['$group']['_id'] = '$chn'
    items = mg.device_stats.aggregate(cond)
    for item in items:
        key = '%s-%s' % (day, item['_id'])
        mg.channel_report.update_one({'_id': key},
                                     {'$set': {'stay_{}'.format(n): item['count']}})

    items = mg.user_stats.aggregate(cond)
    for item in items:
        key = '%s-%s' % (day, item['_id'])
        mg.channel_report.update_one({'_id': key},
                                     {'$set': {'user_stay_{}'.format(n): item['count']}})


def create_recharge_report(day):
    end = day + timedelta(days=1)
    value = {'recharge_count': 0,
             'win_count': 0,
             'gain_count': 0,
             'lose_count': 0,
             'recharge_price': 0,
             'gain_amount': 0,
             'lose_amount': 0,
             }
    base = deepcopy(value)
    fresh_value = deepcopy(base)
    for k in [(1, 2), (3, 10), (11, 50), (51, 100), (101, 500), (501, 1000),
              (1001, 2000), (2001, 4000), (4001, 8000), (8001, 15000),
              (15000, None)]:
        filters = {'recharge.total': {'$gte': k[0]}}
        key = str(k[0]) + '-' + str(k[1])
        if k[1] is not None:
            filters['recharge.total']['$lte'] = k[1]
        # 直接遍历一遍更快
        # 区间充值/中奖/盈利/亏损人数
        filters['updated_at'] = {'$gte': day, '$lt': end}
        items = mg.daily_stats.find(filters)
        value[key] = deepcopy(base)
        fresh_value[key] = deepcopy(base)
        for item in items:
            is_new = False
            if 'created_at' in item:
                # 新用户
                is_new = True
            value[key]['recharge_count'] += 1
            value['recharge_count'] += 1
            recharge = item['recharge']['total']
            total_gain = item.get('total_gain', 0)
            value['recharge_price'] += recharge
            value[key]['recharge_price'] += recharge
            if is_new:
                fresh_value[key]['recharge_count'] += 1
                fresh_value['recharge_count'] += 1
                fresh_value['recharge_price'] += recharge
                fresh_value[key]['recharge_price'] += recharge
            win = item.get('win', {}).get('total', 0)
            if win > 0:
                value[key]['win_count'] += 1
                value['win_count'] += 1
                if is_new:
                    fresh_value[key]['win_count'] += 1
                    fresh_value['win_count'] += 1
            if total_gain > 0:
                value[key]['gain_count'] += 1
                value['gain_count'] += 1
                value[key]['gain_amount'] += total_gain
                value['gain_amount'] += total_gain
                if is_new:
                    fresh_value[key]['gain_count'] += 1
                    fresh_value['gain_count'] += 1
                    fresh_value[key]['gain_amount'] += total_gain
                    fresh_value['gain_amount'] += total_gain
            elif total_gain < 0:
                value[key]['lose_count'] += 1
                value['lose_count'] += 1
                value[key]['lose_amount'] += total_gain
                value['lose_amount'] += total_gain
                if is_new:
                    fresh_value[key]['lose_count'] += 1
                    fresh_value['lose_count'] += 1
                    fresh_value[key]['lose_amount'] += total_gain
                    fresh_value['lose_amount'] += total_gain
    # 未充值统计
    items = mg.daily_stats.find({
        'updated_at': {'$gte': day, '$lt': end},
        'recharge': {'$exists': 0}
    })
    value['0-0'] = deepcopy(base)
    fresh_value['0-0'] = deepcopy(base)
    for item in items:
        is_new = False
        if 'created_at' in item:
            # 新用户
            is_new = True
        total_gain = item.get('total_gain', 0)
        win = item.get('win', {}).get('total', 0)
        if win > 0:
            value['0-0']['win_count'] += 1
            value['win_count'] += 1
            if is_new:
                fresh_value['0-0']['win_count'] += 1
                fresh_value['win_count'] += 1
        if total_gain > 0:
            value['0-0']['gain_count'] += 1
            value['gain_count'] += 1
            value['0-0']['gain_amount'] += total_gain
            value['gain_amount'] += total_gain
            if is_new:
                fresh_value['0-0']['gain_count'] += 1
                fresh_value['gain_count'] += 1
                fresh_value['0-0']['gain_amount'] += total_gain
                fresh_value['gain_amount'] += total_gain
        elif total_gain < 0:
            value['0-0']['lose_count'] += 1
            value['lose_count'] += 1
            value['0-0']['lose_amount'] += total_gain
            value['lose_amount'] += total_gain
            if is_new:
                fresh_value['0-0']['lose_count'] += 1
                fresh_value['lose_count'] += 1
                fresh_value['0-0']['lose_amount'] += total_gain
                fresh_value['lose_amount'] += total_gain
    key = {'_id': utc_to_local(day).strftime('%Y-%m-%d')}
    mg.recharge_report.update_one(key, {'$set': value}, upsert=True)
    mg.fresh_recharge_report.update_one(
        key, {'$set': fresh_value}, upsert=True)


def update_recharge_report(day):
    end = day + timedelta(days=1)
    # 更新前日的回流数据
    update = {
        '2_back_count': 0,  # 次日回流
        '2_recharge_count': 0,  # 次日付费
        '2_win_back_count': 0,  # 中奖次日回流
        '2_win_recharge_count': 0,  # 中奖次日付费
        '2_gain_back_count': 0,  # 次日赢家回流
        '2_gain_recharge_count': 0,  # 次日赢家付费
        '2_lose_back_count': 0,  # 次日输家回流
        '2_lose_recharge_count': 0,  # 次日输家付费
    }
    base = deepcopy(update)
    fresh_update = deepcopy(base)
    _id = utc_to_local(day).strftime('%Y-%m-%d')
    x = mg.recharge_report.find_one({'_id': _id})
    if not x:
        return
    for k in [(1, 2), (3, 10), (11, 50), (51, 100), (101, 500), (501, 1000),
              (1001, 2000), (2001, 4000), (4001, 8000), (8001, 15000),
              (15000, None)]:
        filters = {'recharge.total': {'$gte': k[0]}}
        key = ('%s-%s_back' % (k[0], k[1]))
        if k[1] is not None:
            filters['recharge.total']['$lte'] = k[1]
        filters['updated_at'] = {'$gte': day, '$lt': end}
        items = mg.daily_stats.find(filters)  # 当日充值区间的所有活跃
        fresh_update[key] = deepcopy(base)
        update[key] = deepcopy(base)
        for item in items:
            data = mg.daily_stats.find_one({'_id': '%s-%s' % (
                item['user_id'], utc_to_local(end).strftime('%Y-%m-%d'))})
            if not data:
                continue
            is_new = False
            if 'created_at' in item:
                is_new = True
            update[key]['2_back_count'] += 1
            update['2_back_count'] += 1
            if is_new:
                fresh_update[key]['2_back_count'] += 1
                fresh_update['2_back_count'] += 1
            recharged = False
            if data.get('recharge', {}).get('total', 0) > 0:
                update[key]['2_recharge_count'] += 1
                update['2_recharge_count'] += 1
                if is_new:
                    fresh_update[key]['2_recharge_count'] += 1
                    fresh_update['2_recharge_count'] += 1
                recharged = True
            win = item.get('win', {}).get('total', 0)
            if win > 0:
                update[key]['2_win_back_count'] += 1
                update['2_win_back_count'] += 1
                if is_new:
                    fresh_update[key]['2_win_back_count'] += 1
                    fresh_update['2_win_back_count'] += 1
                if recharged:
                    update[key]['2_win_recharge_count'] += 1
                    update['2_win_recharge_count'] += 1
                    if is_new:
                        fresh_update[key]['2_win_recharge_count'] += 1
                        fresh_update['2_win_recharge_count'] += 1
            gain = item.get('total_gain', 0)
            if gain > 0:
                update[key]['2_gain_back_count'] += 1
                update['2_gain_back_count'] += 1
                if is_new:
                    fresh_update[key]['2_gain_back_count'] += 1
                    fresh_update['2_gain_back_count'] += 1
                if recharged:
                    update[key]['2_gain_recharge_count'] += 1
                    update['2_gain_recharge_count'] += 1
                    if is_new:
                        fresh_update[key]['2_gain_recharge_count'] += 1
                        fresh_update['2_gain_recharge_count'] += 1
            if gain < 0:
                update[key]['2_lose_back_count'] += 1
                update['2_lose_back_count'] += 1
                if is_new:
                    fresh_update[key]['2_lose_back_count'] += 1
                    fresh_update['2_lose_back_count'] += 1
                if recharged:
                    update[key]['2_lose_recharge_count'] += 1
                    update['2_lose_recharge_count'] += 1
                    if is_new:
                        fresh_update[key]['2_lose_recharge_count'] += 1
                        fresh_update['2_lose_recharge_count'] += 1
    mg.recharge_report.update_one({'_id': _id}, {'$set': update})
    mg.fresh_recharge_report.update_one({'_id': _id}, {'$set': fresh_update})


def create_activity_report(day):
    key = utc_to_local(day).strftime('%Y-%m-%d')
    group = {'_id': None}
    for k in ('pay_amount', 'pay_money', 'used_coupon', 'win_count', 'win_amount'):
        group[k] = {'$sum': '$%s' % k}
    t = mg.daily_acs.aggregate([
        {'$match': {'day': key}},
        {'$group': group}
    ])
    result = t.next() if t.alive else {}
    result.pop('_id', None)
    end = day + timedelta(days=1)
    result['payer_count'] = mg.daily_stats.count({
        'pay.total': {'$gt': 0},
        'updated_at': {'$gte': day, '$lt': end}
    })
    result['winner_count'] = mg.daily_stats.count({
        'win.total': {'$gt': 0},
        'updated_at': {'$gte': day, '$lt': end}
    })
    # 盈利用户数、元宝数
    t = mg.daily_stats.aggregate([
        {'$match': {'$and': [
            {'updated_at': {'$gte': day, '$lt': end}},
            {'total_gain': {'$gt': 0}}
        ]}},
        {'$group': {'_id': None, 'count': {'$sum': 1},
                    'amount': {'$sum': '$total_gain'}}}
    ])
    t = t.next() if t.alive else {}
    result['gain_count'] = t.get('count', 0)
    result['gain_amount'] = t.get('amount', 0)
    # 亏损用户数， 亏损金额
    t = mg.daily_stats.aggregate([
        {'$match': {'$and': [
            {'updated_at': {'$gte': day, '$lt': end}},
            {'total_gain': {'$lt': 0}}
        ]}},
        {'$group': {'_id': None, 'count': {'$sum': 1},
                    'amount': {'$sum': '$total_gain'}}}
    ])
    t = t.next() if t.alive else {}
    result['lose_count'] = t.get('count', 0)
    result['lose_amount'] = t.get('amount', 0)

    group = {'_id': None}
    default = {}
    for k in ('payer_count', 'pay_amount', 'win_count', 'win_amount'):
        group[k] = {'$sum': '$%s' % k}
        default[k] = 0
    dist = []
    result['dist'] = dist
    mg.activity_report.update_one({'_id': key}, {'$set': result}, upsert=True)


def create_coupon_report(day):
    data = {
        'gen_amount': 0,
        'expire_amount': 0,
        'gen_dist': {},
        'cost_amount': 0,
        'cost_user': 0,
        'cost_dist': {},
        'balance': 0
    }
    end = day + timedelta(days=1)
    # 产生/消耗/剩余红包价格
    groups = mg.coupon.aggregate([
        {'$match': {'created_at': {'$gte': day, '$lt': end}}},
        {'$group': {'_id': '$from', 'price': {'$sum': '$price'}}}
    ])
    for group in groups:
        data['gen_dist'][group['_id']] = group['price']
        data['gen_amount'] += group['price']

    groups = mg.coupon.aggregate([
        {'$match': {'use_at': {'$gte': day, '$lt': end}}},
        {'$group': {'_id': '$title', 'price': {'$sum': '$price'}}}
    ])
    for group in groups:
        data['cost_dist'][group['_id']] = group['price']
        data['cost_amount'] += group['price']
    t = mg.coupon.aggregate([
        {'$match': {'expire_at': {'$gte': day, '$lt': end}}},
        {'$group': {'_id': None, 'price': {'$sum': '$price'}}}
    ])
    t = t.next() if t.alive else {}
    data['expire_amount'] = t.get('price', 0)
    balance = slave.session.query(func.sum(AccountCoupon.price)).join(
        Account, Account.id == AccountCoupon.user_id).filter(
        Account.is_virtual == False).filter(
        AccountCoupon.status == COUPON_STATUS.UNUSED).scalar() or 0
    data['balance'] = int(float(balance))
    t = mg.coupon.aggregate([
        {'$match': {'use_at': {'$gte': day, '$lt': end}}},
        {'$group': {'_id': '$user_id', 'price': {'$sum': '$price'}}},
        {'$group': {'_id': None, 'user_count': {'$sum': 1}}}
    ])
    t = t.next() if t.alive else {}
    data['cost_user'] = t.get('user_count', 0)

    # 为了方便聚合
    for k in 'gen_dist', 'cost_dist':
        d = data.pop(k)
        new = []
        for t, v in d.iteritems():
            new.append({'type': t, 'amount': v})
        data[k] = new
    mg.coupon_report.update_one(
        {'_id': utc_to_local(day).strftime('%Y-%m-%d')},
        {'$set': data}, upsert=True)


def main(delta):
    today = get_utc_date()
    yesterday = today - timedelta(days=1)
    day = today - timedelta(days=delta)
    now = local_now()

    if now.hour == 0:
        day = yesterday

    print local_now(), 'updating daily shipping report...'
    
    if now.hour > 1 and now.hour < 7:
        print 'abort...'
        # return
    update_day = day - timedelta(days=1)
    print now, 'updating daily_report for utc time %s...' % day
    create_daily_report(day)
    fix_daily_recharge(day)
    print local_now(), 'updating channel_report...'
    create_channel_report(day)
    if now.hour % 2 == 0:
        print local_now(), 'updating stay 2...'
        update_stay_N_count(day, 1)
        print local_now(), 'updating stay 3...'
        update_stay_N_count(day, 3)
        print local_now(), 'updating stay 7...'
        update_stay_N_count(day, 7)
        print local_now(), 'updating recharge report...'
        create_recharge_report(day)
        print local_now(), 'updating recharge back data...'
        update_recharge_report(update_day)

    new_users = Account.query.filter(Account.created_at > today,
                                     Account.created_at < today + timedelta(days=1)).all()
    new_userid_list = [new_user.id for new_user in new_users]
    print local_now(), 'updating fruit report...'
    create_fruit_report(day, new_userid_list)
    print local_now(), 'updating kfc report...'
    create_kfc_report(day, new_userid_list)
    print local_now(), 'updating lottery report...'
    create_lottery_report(day, new_userid_list)
    print local_now(), 'updating bull report...'
    create_bull_report(day, new_userid_list)
    print local_now(), 'updating metis report...'
    create_metis_report(day, new_userid_list)


if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument("-p", "--period", dest="period", help="update today to today -n days",
                        type=int)
    args = parser.parse_args()
    print args
    period = args.period if args.period else 0
    for delta in range(0, period + 1):
        main(delta)
